/**
 * 
 */
package com.gosophia.conferenceManagement.common.service.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.gosophia.commons.exception.BusinessException;
import com.gosophia.conferenceManagement.ConferenceConfiguration;
import com.gosophia.conferenceManagement.ConferenceTurningAction;
import com.gosophia.conferenceManagement.common.entity.ConferenceJobData;
import com.gosophia.conferenceManagement.common.service.ConferenceHandleService;
import com.gosophia.conferenceManagement.dao.ConferenceJobDataDAO;
import com.gosophia.conferenceManagement.jbpm.JobConfiguration;
import com.gosophia.conferenceManagement.jbpm.NodeConfiguration;
import com.gosophia.conferenceManagement.scheme.entity.SchemeJobData;
import com.gosophia.conferenceManagement.starting.entity.ConferenceApplicationJobData;
import com.gosophia.conferenceManagement.starting.entity.ConferenceStartingJobData;
import com.gosophia.dataDictionary.entity.DataValue;
import com.gosophia.dataDictionary.service.DataDictionaryService;
import com.gosophia.taskManagement.entity.Job;
import com.gosophia.taskManagement.entity.Mission;
import com.gosophia.taskManagement.service.TaskManagementService;
import com.gosophia.userManagement.entity.UserInfo;
import com.gosophia.userManagement.service.UserManagementService;

/**
 * 功能：会议流程处理 service 接口实现      
 * @author zhangdongsheng
 * @since  2011-3-24
 *  Copyright (c) 2010 Gosophia corporation All Rights Reserved
 */
@Transactional
@Service("conferenceHandleService")
public class ConferenceHandleServiceImpl  implements ConferenceHandleService{
	
   @Autowired
   private TaskManagementService taskManagementService;
   
   @Autowired
   private DataDictionaryService dataDictionaryService;
   
   @Autowired
   private ConferenceConfiguration conferenceConfiguration;
   
   @Autowired
   private ConferenceJobDataDAO conferenceJobDataDAO;
  
   @Autowired
   private UserManagementService userManagementService; 
   
   private final Logger logger = Logger.getLogger(this.getClass());
   @Override
    public void addConferenceJobData(ConferenceJobData conferenceJobData) throws BusinessException{
        Assert.notNull(conferenceJobData, "conferenceJobData不能为null");
        Assert.isNull(conferenceJobData.getJobDataId(), "jobDataId必须为null");
        conferenceJobDataDAO.save(conferenceJobData);
    }

   
    @Override
    public ConferenceJobData findConferenceJobDataByJobDataId(
            Long conferenceJobDataId) {
        // TODO Auto-generated method stub
        return null;
    }

    //处理会议流转
    @Override
    public void HandleConferenceTurning(Long jobId,Long operatorId, ConferenceJobData conferenceJobData) throws BusinessException {
    
        Assert.notNull(jobId,"将被处理的任务[Id]不能为空");
        logger.debug("处理会议流转 method:【HandleConferenceTurning】 参数信息：jobId："+jobId 
                +" operatorId:"
                    + operatorId+" jobData："
                        +conferenceJobData.toString() );
        logger.debug("处理动作：["+conferenceJobData.getTurningAction()+"]开始");
        String jobStatus =conferenceConfiguration.DEFAULT_JOB_STATUS_AFTER_HANDLED;// 获取操作动作后的任务状态,此处使用默认值
        
        //下一个处理人不为null
        if(conferenceJobData.getNextApprovalId()!=null){
            conferenceJobData.setNextApproval(userManagementService.findUserInfoByUserInfoId(conferenceJobData.getNextApprovalId()));
        }
        Job toHandleJob = taskManagementService.findJobDetailByJobId(jobId);
        String transitionName = getTransitionNameAfterAction(conferenceJobData.getTurningAction());//获取迁移路径名称
        String missionStatus = getMissionStatusAfterCurrentJobHandleAction(toHandleJob.getJobType(),transitionName,jobId, conferenceJobData);// 获取操作动作后的大任务状态
        
        
        conferenceJobData.setJob(toHandleJob);
        Map jobContext = validHandleJobNeedContext(conferenceJobData);
        if(ConferenceTurningAction.JUMP_ACTION.getValue().equals(conferenceJobData.getTurningAction())){
        	//TODO:考虑跳过要存储的字段
        	conferenceJobData=new ConferenceJobData();
        	conferenceJobData.setJob(toHandleJob);
        }
        if(jobContext!=null){
            taskManagementService.processJob(conferenceJobData, jobStatus, missionStatus, jobId, operatorId, transitionName, jobContext);
        }else{
        	taskManagementService.processJob(conferenceJobData, jobStatus, missionStatus, jobId, operatorId, transitionName);
        }
        logger.debug("处理动作：["+conferenceJobData.getTurningAction()+"]"+ "成功");
    }

    private Map validHandleJobNeedContext(ConferenceJobData jobData){
        //此处判定，当从任务系统发起的会议大任务，处理会议起草任务需要传入会议类型和是否直接发起
        if(jobData!=null ){
            Map context = new HashMap();
            if(jobData instanceof ConferenceStartingJobData){
                ConferenceStartingJobData stJobData = (ConferenceStartingJobData)jobData;
                context.put(conferenceConfiguration.CONFERENCE_MODEL, stJobData.getConferenceModel());
                context.put(conferenceConfiguration.CONFERENCE_TYPE,stJobData.getConferenceType());
            }
            if(jobData instanceof ConferenceApplicationJobData){
                ConferenceApplicationJobData appJobData = (ConferenceApplicationJobData)jobData;
                context.put(conferenceConfiguration.CONFERENCE_APP_ASSIGN,appJobData.getConfernceUnderTaker().getUserInfoId());
            }
            return context;
        }
       
        return null;
    }
    
    /* 开启会议大流程
     * 注意：直接发起流程，注意此处无需关注从任务系统发起的情况，从任务发起的会议任务不使用此接口
     * @see com.gosophia.conferenceManagement.common.service.ConferenceHandleService#startingConferenceProcessing(com.gosophia.conferenceManagement.starting.entity.ConferenceBasicInfo)
     */
    @Override
    public Mission startingConferenceProcessing(SchemeJobData schemeJobData) throws BusinessException {
        
        logger.debug("从会议系统发起,创建任务Mission");
        //创建新的mission 
        Mission conferenceMission = new Mission();
        conferenceMission.setMissionName(schemeJobData.getConferenceName());//missionName
        conferenceMission.setScheduleEndDate(schemeJobData.getPlanEndTime());//计划结束时间
        conferenceMission.setDescription(schemeJobData.getConferenceDescription());//任务描述
        conferenceMission.setMissionState("已创建");//任务创建后的状态
        conferenceMission.setMissionType(obatainConferenceMissionType());//设定conferenceMissionType
        conferenceMission.setMissionDetailURL(conferenceConfiguration.getConferenceMissionDetailURL());//详细页面URL
        conferenceMission.setCreator(schemeJobData.getConferenceCreator());//任务发起人
        conferenceMission.setUndertaker(schemeJobData.getConferenceCreator());//任务承办人，此处承办人和发起人同
        conferenceMission.setImportance(schemeJobData.getImportantLevel());//设定任务重要度
        //通过起草方案直接创建mission
        Mission backMission = taskManagementService.addMission(conferenceMission, null);
        logger.debug("从会议管理直接发起mission成功");
		List<Job> firstJobs = taskManagementService.findTodoJobByMissionId(backMission.getMissionId());
		schemeJobData.setJob(firstJobs.get(0));
		logger.info("处理起草任务：jobId："+firstJobs.get(0).getJobId()+"jobType"+firstJobs.get(0).getJobType()+"  承办人："+firstJobs.get(0).getUndertaker().getUserInfoId() );
		
		//完成首个发起任务
		HandleConferenceTurning(firstJobs.get(0).getJobId(), schemeJobData.getConferenceCreator().getUserInfoId(),schemeJobData);
         
        logger.debug("返回会议管理系统直接发起的大任务  code："+backMission .getMissionCode());
        return backMission ;
    }

    
    
    /* (non-Javadoc)
     * @see com.gosophia.conferenceManagement.common.service.ConferenceHandleService#updateConferenceJobData(com.gosophia.conferenceManagement.common.entity.ConferenceJobData)
     */
    @Override
    public void updateConferenceJobData(ConferenceJobData conferenceJobData) {
        Assert.notNull(conferenceJobData, "conferenceJobData不能为null");
        Assert.notNull(conferenceJobData.getJobDataId(), "jobDataId不能为null");
        conferenceJobDataDAO.update(conferenceJobData);
        
    }
    //根据当前的处理动作名称获取 动作处理后的missionStatus
    private String getMissionStatusAfterCurrentJobHandleAction(String jobType,String actionName, Long jobId, ConferenceJobData conferenceJobData) throws BusinessException{
         //处理方法说明：方法一，以jobType和actionName 为key，对应missionStatus为value，构建映射
        //处理方法二：根据actionName 获取当前的transitionName，获取transition的目标节点，获取目标节点的jobtype
        //此处使用方法1
        //获取conferenceConfiguration信息
        
        if(actionName==null||"".equals(actionName)){
            actionName="default";
        }
        String mappedMissionStatus="";
       Collection<NodeConfiguration> nodeConfValues = conferenceConfiguration.getNodeConfigurations().values();
       labelA:
       for (NodeConfiguration nodeConfiguration : nodeConfValues) {
           List<JobConfiguration> configJobType = nodeConfiguration.getJobConfs();
           for (JobConfiguration jobConfiguration : configJobType) {
               if(jobType.equals(jobConfiguration.getJobType())){
                   mappedMissionStatus = jobConfiguration.getHandleCommands().get(actionName);
                  if(mappedMissionStatus!=null) break labelA;
                }
              
        }
           
        }
       logger.debug("输出missionStatus："+mappedMissionStatus);
		if ("已创建".equals(mappedMissionStatus)) {
			ConferenceStartingJobData jobData = (ConferenceStartingJobData) conferenceJobData;
			if("applicationConference".equals(jobData.getConferenceModel())){
				mappedMissionStatus = "审批会议申请";
			}else{
				if("middleTypeConference".equals(jobData.getConferenceType())){
					mappedMissionStatus = "会务准备";
				}else{
					mappedMissionStatus = "方案起草";
				}
			}
       }
       if("申请已通过".equals(mappedMissionStatus)){
    	   Job job = taskManagementService.findJobDetailByJobId(jobId);
			ConferenceStartingJobData jobData = (ConferenceStartingJobData) taskManagementService
					.findJobDataDetail(job.getMission().getFirstJob()
							.getJobId(), ConferenceStartingJobData.class);
			String conferenceType = "";
			if(jobData != null){
				conferenceType = jobData.getConferenceType();
			}
			if("middleTypeConference".equals(conferenceType)){
				mappedMissionStatus = "会务准备";
			}else{
				mappedMissionStatus = "方案起草";
			}
       }
       if("方案已定稿".equals(mappedMissionStatus)){
    	   Job job = taskManagementService.findJobDetailByJobId(jobId);
			ConferenceStartingJobData jobData = (ConferenceStartingJobData) taskManagementService
					.findJobDataDetail(job.getMission().getFirstJob()
							.getJobId(), ConferenceStartingJobData.class);
			String conferenceType = "";
			if(jobData != null){
				conferenceType = jobData.getConferenceType();
			}
			if("smallTypeConference".equals(conferenceType)){
				mappedMissionStatus = "总结起草";
			}else{
				mappedMissionStatus = "会务准备";
			}
       }
       
       return mappedMissionStatus;   
    }
     //根据当前的处理动作名称获取 动作处理后的 transitionName（jbpm中的transition name），以确定 流程转向
    private String getTransitionNameAfterAction(String actionName){
        return actionName;
        // return (String)conferenceConfiguration.getActionTransitionMapping().get(actionName);
    }
    
    private DataValue obatainConferenceMissionType(){
        DataValue conferenceMissionType = dataDictionaryService.findDataValueByDataValueId(conferenceConfiguration.getConferenceDataValeId());
        return conferenceMissionType;
    }
    
   private ConferenceStartingJobData loadCompleteInfo(ConferenceStartingJobData sourceData) {
      
       
       
       //检查重要度
       if(sourceData.getImportantLevel()==null){
         Long importantLevId =    sourceData.getImportantLevelId();
        if(importantLevId!=null) {
            DataValue importantLev = dataDictionaryService.findDataValueByDataValueId(importantLevId);
            sourceData.setImportantLevel(importantLev);
        }  
       }
        
        //会议任务发起人
        if(sourceData.getConferenceCreator()==null){
           if(sourceData.getConferenceCreatorId()!=null){
               Long conferenceCreatorId = sourceData.getConferenceCreatorId();
               UserInfo creator = userManagementService.findUserInfoByUserInfoId(conferenceCreatorId);
               sourceData.setConferenceCreator(creator);
           }
        
        }
        
        return sourceData;
   }
           

        
}
